package mnn;

/*
 This program is written by Ahmed Medhat Ahmed
 Egypt
 Alexandria Universty
 Faculty of Science
 Computer Science
 7-7-2007
 a.medhat.cs@gmail.com
 ama_compsc@yahoo.com
 */
/*
 train and old Neral network with updating the old data
 */

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.ScrollPane;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;

import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class TrainO extends JFrame {
	/**
	 * 
	 */
	private static final long serialVersionUID = -3557738319390587045L;

	public static void main(String[] args)// throws
											// FileNotFoundException,IOException,EOFException
	{
		TrainO app = new TrainO();
		app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	private JLabel L1, L2, L_load;
	private JLabel L_c, L_tc, L_in, L_hl, L_hn, L_lr, L_mr;

	private JTextField TF_c, TF_tc, TF_in, TF_hl, TF_hn, TF_lr, TF_mr, TF_load;

	private JButton B_loadim, B_train, B_loadNN;
	private int in, out, hl, hn, no_tc;
	private double lr, mr;
	private BorderLayout layout;
	private GridLayout layoutL, layoutR;
	private Container container;

	private JPanel P_Top, P_Center, P_CenterL, P_CenterR, P_CenterC, P_Right,
			P_Left, P_Bottom, P_CT;

	private ObjectInputStream input;
	private JTextArea ta;

	private ScrollPane sp;
	private int in_array[][][];
	private int out_array[][];
	private String img_names[];

	private File img_files[];
	private String traininfo;
	private int Dim[];

	private int Dim4[];

	private double weight[][][];

	private File SName;
	private ImageP imagep;
	private Train train;

	public TrainO() {

		super("JAVA Neural Networkes");

		container = getContentPane();
		container.setLayout(new BorderLayout(5, 5));

		P_Top = new JPanel();
		P_Top.setLayout(new FlowLayout());

		// Titel = new JLabel();
		// Titel.setText("Neural Networkes main data");
		// Titel.setForeground(Color.RED);
		// Titel.setFont(new Font("Times new Roman",Font.BOLD +
		// Font.ITALIC,26));
		L1 = new JLabel();

		Icon img = new ImageIcon("1.jpg");
		L1.setIcon(img);

		P_Top.add(L1);

		/*
		 * L_inp = new JLabel(); L_inp.setText("Enter the Inputs number");
		 * 
		 * TF_inp = new JTextField(5);
		 */
		/************************************************************************************/
		layout = new BorderLayout();
		P_Center = new JPanel();
		P_Center.setLayout(layout);

		P_CT = new JPanel();
		P_CT.setLayout(new FlowLayout(FlowLayout.LEFT));

		P_CenterC = new JPanel();
		P_CenterC.setLayout(layout);

		layoutR = new GridLayout(7, 1, 10, 10);
		P_CenterR = new JPanel();
		P_CenterR.setLayout(layoutR);

		layoutL = new GridLayout(7, 1, 10, 10);
		P_CenterL = new JPanel();
		P_CenterL.setLayout(layoutL);

		// layoutR.setAlignment(FlowLayout.LEFT);
		// layoutL.setAlignment(FlowLayout.LEFT);

		B_loadNN = new JButton("Browes");
		B_loadNN.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				/* Train the neural network With out set the waites */
				openstructuer();

			}
		});

		L_load = new JLabel(
				"Load Neural Networks structer                     ");
		L_c = new JLabel("The number of classes                      ");
		L_tc = new JLabel("The number of training cases in each class ");
		L_in = new JLabel("The input value                            ");
		L_hl = new JLabel("The number of hidden layer                 ");
		L_hn = new JLabel("The number of hidden neurons               ");
		L_lr = new JLabel("The value of learnning rate                ");
		L_mr = new JLabel("The value of momentum rate                 ");

		TF_load = new JTextField(25);
		TF_c = new JTextField(10);
		TF_tc = new JTextField(10);
		TF_in = new JTextField(10);
		TF_hl = new JTextField(10);
		TF_hn = new JTextField(10);
		TF_lr = new JTextField(10);
		TF_mr = new JTextField(10);

		TF_load.setEditable(false);
		TF_c.setEditable(false);
		TF_in.setEditable(false);
		TF_hl.setEditable(false);
		TF_hn.setEditable(false);
		TF_lr.setEditable(false);
		TF_mr.setEditable(false);

		P_CT.add(L_load);
		P_CT.add(TF_load);
		P_CT.add(B_loadNN);
		/*
		 * P_CenterL.add(L_load); P_CenterR.add(TF_load);
		 * P_CenterR.add(B_loadNN);
		 */
		P_CenterL.add(L_c);
		P_CenterR.add(TF_c);

		P_CenterL.add(L_tc);
		P_CenterR.add(TF_tc);

		P_CenterL.add(L_in);
		P_CenterR.add(TF_in);

		P_CenterL.add(L_hl);
		P_CenterR.add(TF_hl);

		P_CenterL.add(L_hn);
		P_CenterR.add(TF_hn);

		P_CenterL.add(L_lr);
		P_CenterR.add(TF_lr);

		P_CenterL.add(L_mr);
		P_CenterR.add(TF_mr);

		P_Right = new JPanel();
		P_Right.setLayout(new FlowLayout());
		// P_Right.add(L1);

		L2 = new JLabel();
		P_Left = new JPanel();
		P_Left.setLayout(new FlowLayout());
		P_Left.add(L2);

		P_Center.add(P_CT, BorderLayout.NORTH);
		P_Center.add(P_CenterL, BorderLayout.WEST);
		P_Center.add(P_CenterR, BorderLayout.CENTER);
		P_Center.add(P_Right, BorderLayout.EAST);

		B_loadim = new JButton("Load Images");
		B_train = new JButton("Train");
		B_train.setEnabled(false);

		B_loadim.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				openFile();
			}
		});
		B_train.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				/* Train the neural network With out set the waites */
				conv_img();
				get_output();
				train();
				printweight();
			}
		});

		JPanel p1 = new JPanel();
		p1.setLayout(new FlowLayout());
		JPanel p2 = new JPanel();
		p2.setLayout(new FlowLayout());
		P_Bottom = new JPanel();
		P_Bottom.setLayout(new BoxLayout(P_Bottom, BoxLayout.Y_AXIS));

		ta = new JTextArea();
		sp = new ScrollPane();
		sp.add(ta);
		// /ta.setSize(50,100);
		sp.setSize(350, 150);
		p1.add(sp);

		p2.add(B_loadim);
		p2.add(B_train);

		/*
		 * P_Bottom.add(B_savenn); P_Bottom.add(B_loadim);
		 * P_Bottom.add(B_train);
		 */
		P_Bottom.add(p1);
		P_Bottom.add(p2);

		container.add(P_Top, BorderLayout.NORTH);
		container.add(P_Center, BorderLayout.CENTER);
		container.add(P_Bottom, BorderLayout.SOUTH);
		container.add(P_Right, BorderLayout.EAST);
		container.add(P_Left, BorderLayout.WEST);

		setLocation(150, 50);
		pack();
		setVisible(true);
		setResizable(false);
	}

	void conv_img() {
		imagep = new ImageP();
		in_array = new int[out][no_tc][in];
		// JOptionPane.showMessageDialog(this,"in"+in+"   out="+out+"   no_tc="+no_tc);
		for (int i = 0; i < out; i++) {
			for (int j = 0; j < no_tc; j++) {
				in_array[i][j] = imagep.conv_to_data(img_files[(i * no_tc + j)]
						.getAbsolutePath(), in);
				/*
				 * for(int k= 0 ; k<in; k++) {
				 * //JOptionPane.showMessageDialog(this
				 * ,"i="+i+"   j="+j+"   k="+k);
				 * //JOptionPane.showMessageDialog(this,
				 * img_files[(i*no_tc+j)].getAbsolutePath()+"---->"+
				 * in_array[i][j][k]); }
				 */
			}
		}
	}

	void get_output() {
		out_array = new int[out][out];
		for (int i = 0; i < out; i++)
			for (int j = 0; j < out; j++)
				out_array[i][j] = (i == j ? 1 : 0);
	}

	private void openFile() {
		if (TF_tc.getText().equals(""))
			no_tc = 1;
		else
			no_tc = Integer.parseInt(TF_tc.getText());

		JFileChooser fileChooser = new JFileChooser();
		fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		int result = fileChooser.showOpenDialog(this);
		if (result == JFileChooser.CANCEL_OPTION) {
			return;
		} else
			B_train.setEnabled(true);
		File DName = fileChooser.getSelectedFile();

		if (DName == null || DName.getName().equals(""))
			JOptionPane.showMessageDialog(this, "Invalid File Name",
					"Invalid file name", JOptionPane.ERROR_MESSAGE);
		else {
			if (DName.exists()) {
				String files[] = DName.list();
				File fl[] = new File[files.length];
				int counter = 0;
				for (int i = 0; i < files.length; i++) {
					fl[i] = new File(DName.getAbsolutePath() + "\\" + files[i]);
					if (!fl[i].isHidden() && fl[i].isFile()) {
						counter++;
					}
				}
				img_names = new String[counter];
				img_files = new File[counter];
				counter = 0;
				for (int i = 0; i < files.length; i++) {
					if (!fl[i].isHidden() && fl[i].isFile()) {
						img_names[counter++] = files[i];
					}
				}
				for (int i = 0; i < img_names.length; i++) {
					img_files[i] = new File(DName.getAbsolutePath() + "\\"
							+ img_names[i]);
					// JOptionPane.showMessageDialog(this,img_files[i]);
				}
			} else {
				JOptionPane.showMessageDialog(this, DName + " dosent exist");
			}
		}
	}

	private void openstructuer() {
		JFileChooser fileChooser = new JFileChooser();
		fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
		int result = fileChooser.showOpenDialog(this);
		while (result == JFileChooser.CANCEL_OPTION) {
			JOptionPane
					.showMessageDialog(
							this,
							" You must enter the file which contain a structuer of Neural Network ",
							"Invalid file name", JOptionPane.ERROR_MESSAGE);
			result = fileChooser.showOpenDialog(this);
			// return;
		}
		SName = fileChooser.getSelectedFile();

		if (SName == null || SName.getName().equals(""))
			JOptionPane.showMessageDialog(this, "Invalid File Name",
					"Invalid file name", JOptionPane.ERROR_MESSAGE);
		else {
			TF_load.setText(SName.getAbsolutePath());
			try {
				input = new ObjectInputStream(new FileInputStream(SName));
			} catch (IOException ioException) {
				JOptionPane.showMessageDialog(this, "Invalid File Name",
						"Error in opening file", JOptionPane.ERROR_MESSAGE);
			}
			try {
				if (SName.exists()) {
					if (SName.isFile()) {
						StructuerNN struct = (StructuerNN) input.readObject();
						String values[] = { String.valueOf(struct.getinput()),
								String.valueOf(struct.getoutput()),
								String.valueOf(struct.gethl()),
								String.valueOf(struct.gethn()),
								String.valueOf(struct.getlr()),
								String.valueOf(struct.getmr()) };

						TF_c.setText(values[1]);
						TF_in.setText(values[0]);
						TF_hl.setText(values[2]);
						TF_hn.setText(values[3]);
						TF_lr.setText(values[4]);
						TF_mr.setText(values[5]);

						in = struct.getinput();
						out = struct.getoutput();

						if (TF_tc.getText().equals(""))
							no_tc = 1;
						else
							no_tc = Integer.parseInt(TF_tc.getText());

						hl = struct.gethl();
						hn = struct.gethn();
						lr = struct.getlr();
						mr = struct.getmr();

					}
				} else {
					JOptionPane
							.showMessageDialog(this, SName + " dosent exist");
				}
			} catch (NumberFormatException formatException) {
				JOptionPane.showMessageDialog(this, "bad ",
						"Invalied  Number Format", JOptionPane.ERROR_MESSAGE);
			} catch (IOException ioException) {
				JOptionPane.showMessageDialog(this, "Invalid File Name",
						"Error in opening file", JOptionPane.ERROR_MESSAGE);
			} catch (ClassNotFoundException E) {
				JOptionPane.showMessageDialog(this, "Class not found",
						"Error in opening file", JOptionPane.ERROR_MESSAGE);
			}
		}

	}

	void printweight() {

		FileWriter fw;
		BufferedWriter bw;
		String filexls;

		filexls = SName.getAbsolutePath() + ".xls";
		File F = new File(filexls);
		if (F.exists())
			F.delete();

		try {
			fw = new FileWriter(filexls);
			bw = new BufferedWriter(fw);

			for (int i = 0; i < Dim[0]; i++) {
				for (int j = 0; j < Dim4[i]; j++) { // no of in nodes
					for (int k = 0; k < Dim4[i + 1]; k++) {// out nodes
						fw.append(weight[i][j][k] + " \n");
					}
				}
			}
			fw.close();
			bw.close();
			fw = null;
			bw = null;
		} catch (IOException ex) {
			JOptionPane.showMessageDialog(null, "Cant Save the weights");
		}
	}

	void train() {
		Dim = new int[3];

		train = new Train(in, out, hl, hn, lr, mr, no_tc);
		train.start(in_array, out_array);

		traininfo = train.train_info();
		train.getweightsDim(Dim);

		weight = new double[Dim[0]][Dim[2]][Dim[2]];
		Dim4 = new int[Dim[1]];

		train.getweights(weight, Dim4);

		ta.setText(traininfo);
	}

}